const qiniu = require('qiniu');
const axios = require('axios');
const { nanoid } = require('nanoid');
const config = require('../config');
const mac = new qiniu.auth.digest.Mac(config.qiniu.accessKey, config.qiniu.secretKey);
class ImagesController {
  async getImages(ctx) {
    const page = parseInt(ctx.query.page) || 1;
    const pageSize = parseInt(ctx.query.pageSize) || 10;
    const { items: images, total } = await this.fetchImagesFromQiniu(page, pageSize);
    ctx.body = {
      images,
      total
    };
  }
  async uploadImage(ctx) {
    const { file } = ctx.request.files;
    const ext = file.name.split('.').pop();
    const key = `${nanoid()}.${ext}`;
    const options = {
      scope: config.qiniu.bucket,
      expires: 7200
    };
    const putPolicy = new qiniu.rs.PutPolicy(options);
    const uploadToken = putPolicy.uploadToken(mac);
    const response = await axios.post(config.qiniu.uploadUrl, file, {
      headers: {
        'Content-Type': 'application/octet-stream',
        'Authorization': `UpToken ${uploadToken}`
      }
    });
    if (response.status === 200) {
      ctx.status = 201;
      ctx.body = {
        key,
        hash: response.data.hash
      };
    } else {
      ctx.throw(response.status, '上传图片失败');
    }
  }
  async deleteImage(ctx) {
    const { name } = ctx.params;
    const options = {
      scope: `${config.qiniu.bucket}:${name}`
    };
    const deletePolicy = new qiniu.rs.DeletePolicy(options);
    const deleteToken = deletePolicy.deleteToken(mac);
    const response = await axios.post(`${config.qiniu.rsUrl}/${deleteToken}`);
    if (response.status === 200) {
      ctx.status = 204;
    } else {
      ctx.throw(response.status, '删除图片失败');
    }
  }
  async fetchImagesFromQiniu(page, pageSize) {
    const options = {
      scope: config.qiniu.bucket,
      limit: pageSize,
      prefix: '',
      marker: (page - 1) * pageSize
    };
    const bucketManager = new qiniu.rs.BucketManager(mac, new qiniu.conf.Config());
    const { items, marker: nextMarker } = await new Promise((resolve, reject) => {
      bucketManager.listPrefix(config.qiniu.bucket, options, (err, respBody, respInfo) => {
        if (err) {
          reject(err);
        } else if (respInfo.statusCode === 200) {
          const { items, marker } = respBody;
          resolve({ items, marker });
        } else {
          reject(new Error('获取图片列表失败'));
        }
      });
    });
    const total = await new Promise((resolve, reject) => {
      bucketManager.stat(config.qiniu.bucket, null, (err, respBody, respInfo) => {
        if (err) {
          reject(err);
        } else if (respInfo.statusCode === 200) {
          resolve(respBody.itemCount);
        } else {
          reject(new Error('获取图片总数失败'));
        }
      });
    });
    return { items, total };
  }
}
module.exports = new ImagesController();